//
//  RSShowStarView.m
//  RSStarRating
//
//  Created by thinkjoy on 16/8/24.
//  Copyright © 2016年 thinkjoy. All rights reserved.
//

#import "RSShowStarView.h"
#import "RSStarView.h"

@interface RSShowStarView ()


/**
 *  记录添加星星视图的背景颜色
 */
@property   (nonatomic,strong)  UIColor *  bgColor;

/**
 *  分数
 */
@property (nonatomic, assign) CGFloat score;

/**
 *  满值分数，默认为星星的个数
 */
//@property (nonatomic, assign) CGFloat maxScore;

/**星星总数*/
@property   (nonatomic,assign,readwrite)  NSInteger   starCount;

@property (nonatomic, strong) NSMutableArray *starArray;

/**用来存放计算好星星的尺寸*/
@property   (nonatomic,strong)  NSMutableArray *  starFrameMuAry;

/**星星之间的间隔*/
@property   (nonatomic,assign)  CGFloat  space;

/**
 初始化的间距
 */
@property   (nonatomic,assign)  CGFloat  initSpace;

/**
 初始化边距
 */
@property   (nonatomic,assign)  CGFloat  starMargin;

/**
 第一个星星居左和最后一个星星居右的值；居左时Left有效，居右时Right有效，居中都无效，两端对齐Left、Right有效;Left和Right默认为5
 */
@property   (nonatomic,assign)  UIEdgeInsets  starsEdgeInsets;

/**
 星星的大小
 */
@property (nonatomic, assign) CGFloat star_WY;

@end


@implementation RSShowStarView
#pragma mark -

/**
 创建一个只读、居中对齐、间距和边距都为5、显示完整星星、星星大小为当前视图高度的控件

 @param frame 如当前控件过小，放不下对应的星星数量时，Debug模式会报错
 @param starCount 星星个数
 @param defaultScore 点亮星星数量
 @return return
 */
- (instancetype)initWithFrame:(CGRect)frame
                    starCount:(NSInteger)starCount
                 defaultScore:(CGFloat)defaultScore
{
    return [self initWithFrame:frame showStarStyle:RSShowStarStyleReadonly starAlignment:RSShowStarAlignmentJustified showStarDrawStyle:RSShowStarDrawStyleComplete starCount:starCount defaultScore:defaultScore starSpace:5.f starMargin:5.f starFont:CGRectGetHeight(frame)];
}
/**
 初始化

 @param frame 如当前控件过小，放不下对应的星星数量时，Debug模式会报错
 @param showStarStyle RSShowStarView的样式 ,默认是只读
 @param starAlignment 对齐方式，默认两端对齐
 @param showStarDrawStyle 星星的绘制方式,默认为整个的 则根据score对应的百分比填充
 @param starCount 星星个数
 @param defaultScore 点亮星星数量
 @param space 间距，默认为5；两端对齐时该参数无效
 @param starMargin 左右边距,默认为5；居中对齐时该参数无效
 @param starFont 星星的大小,最小为5，默认为父视图高度，不得超过父视图高度
 @return return
 */
- (instancetype)initWithFrame:(CGRect)frame
                showStarStyle:(RSShowStarStyle)showStarStyle
                starAlignment:(RSShowStarAlignment)starAlignment
            showStarDrawStyle:(RSShowStarDrawStyle)showStarDrawStyle
                    starCount:(NSInteger)starCount
                 defaultScore:(CGFloat)defaultScore
                    starSpace:(CGFloat)space
               starMargin:(CGFloat)starMargin
                     starFont:(CGFloat)starFont
{
    if (self = [super initWithFrame:frame]) {
        self.showStarStyle  =   showStarStyle;
        _starAlignment  =   starAlignment;
        _showStarDrawStyle  =   showStarDrawStyle;
        _starCount  =   starCount>=0?starCount:0;
        _defaultScore   =   defaultScore>=0?defaultScore:0;
        _space  =   space>=0?space:0;
        _initSpace  =   _space;
        _starMargin  =   starMargin>=0?starMargin:0;
        _starsEdgeInsets    =   UIEdgeInsetsMake(0, starMargin, 0, starMargin);
        _star_WY    =   starFont>=5?starFont:5;
        
        
        [self setupConfigurationProperty];
        [self setUpStarViewsWithFrame];
        [self updateViewsWithScore:_defaultScore];
    }
    self.layer.masksToBounds    =   YES;
    return self;
}

#pragma mark    - 设置初始化参数
- (void)setupConfigurationProperty
{
    switch (_starAlignment) {
        case RSShowStarAlignmentJustified:
        {
            _space  =   (self.frame.size.width - _starMargin*2 - _starCount*_star_WY)/(_starCount-1);
            _starsEdgeInsets    =   UIEdgeInsetsMake(0, _starMargin, 0, _starMargin);   //对齐方式发生改变时重置边距
            NSAssert(_space>=0, @"两边对齐时，RSShowStarView宽度过小，不能放下对应数量星星");
        }
        break;
        case RSShowStarAlignmentLeft:
        {
            _space  =   _initSpace;     //对齐方式发生改变时重置间距
            NSAssert(self.frame.size.width>=_starMargin+_starCount*_star_WY+_space*(_starCount-1), @"左对齐时，RSShowStarView宽度过小，不能放下对应数量星星");
            _starsEdgeInsets    =   UIEdgeInsetsMake(0, _starMargin, 0, 0);//对齐方式发生改变时重置边距
        }
        break;
        case RSShowStarAlignmentCenter:
        {
            _space  =   _initSpace; //对齐方式发生改变时重置间距
            NSAssert(self.frame.size.width>=_starCount*_star_WY+_space*(_starCount-1), @"居中对齐时，RSShowStarView宽度过小，不能放下对应数量星星");
            CGFloat space   =   (self.frame.size.width-_starCount*_star_WY-_space*(_starCount-1))/2.f;
            _starsEdgeInsets    =   UIEdgeInsetsMake(0, space, 0, space);   //对齐方式发生改变时重置边距
        }
        break;
        case RSShowStarAlignmentRight:
        {
            _space  =   _initSpace; //对齐方式发生改变时重置间距
            NSAssert(self.frame.size.width>=_starMargin+_starCount*_star_WY+_space*(_starCount-1), @"右对齐时，RSShowStarView宽度过小，不能放下对应数量星星");
            CGFloat space   =   (self.frame.size.width-_starCount*_star_WY-_space*(_starCount-1))-_starMargin;
            _starsEdgeInsets    =   UIEdgeInsetsMake(0, space, 0, _starMargin); //对齐方式发生改变时重置边距
        }
        break;
        default:
        break;
    }
}



#pragma mark    创建星星
- (void)setUpStarViewsWithFrame{
    [self.starArray removeAllObjects];
    for (int i = 0; i < self.starCount; i++) {
        RSStarView *starView = [[RSStarView alloc] init];
//        starView.backgroundColor = self.bgColor;
        [self addSubview:starView];
        starView.fillColor = self.fillColor;
        starView.lineWidth = self.lineWidth;
        starView.lineColor = self.lineColor;
        starView.tag = i;
        [self.starArray addObject:starView];
    }
}
- (void)layoutSubviews{
    [super layoutSubviews];
    [self upDateStarViews];
}
#pragma mark 计算星星位置
- (void)upDateStarViews
{
    CGFloat starW = self.star_WY;
    CGFloat starH = self.star_WY;
    __block  CGFloat starX = 0;
    __block  CGFloat starY = 0;
    
    [self.starFrameMuAry removeAllObjects];
    
    __block NSMutableArray * muAry  =   [NSMutableArray arrayWithCapacity:_starArray.count];
    [self.starArray enumerateObjectsUsingBlock:^(RSStarView *starView, NSUInteger idx, BOOL * _Nonnull stop) {
        starX   =   _starsEdgeInsets.left + (starW+_space)*idx;
        starY   =   (self.frame.size.height-starH)/2.f;
        
        starView.frame = CGRectMake(starX, starY, starW, starH);
        starView.lineWidth = _lineWidth;
        starView.lineColor = _lineColor;
        starView.fillColor = _fillColor;
        
        [muAry addObject:NSStringFromCGRect(starView.frame)];
        NSLog(@"%@",NSStringFromCGRect(starView.frame));
    }];
    [self.starFrameMuAry addObjectsFromArray:muAry];
    
}

- (CGFloat)cheackReturnScore:(CGFloat)score
{
    CGFloat newRating   =   score;
    switch (_showStarDrawStyle) {
        case RSShowStarDrawStyleComplete:
        {
            newRating   =   newRating>(int)newRating?(int)newRating+1:(int)newRating;
            return newRating;
        }
        break;
        case RSShowStarDrawStyleCompleteAndHalf:
        {
            CGFloat  decimalPart    =   newRating-(int)newRating;
            if (decimalPart>0) {
                if (decimalPart>0.5) {
                    newRating   =   (int)newRating +1;
                }else{
                    newRating   =   (int)newRating +0.5;
                }
            }
            return newRating;
        }
        break;
        case RSShowStarDrawStyleFree:
        {
            return newRating;
        }
        break;
        default:
        break;
    }

}

#pragma mark    根据分数更新、绘制scoreView
- (void)updateViewsWithScore:(CGFloat)score{
    
    __block CGFloat starScore = score;
    
    [self.starArray enumerateObjectsUsingBlock:^(RSStarView *starView, NSUInteger idx, BOOL * _Nonnull stop) {
        
        if (starScore >= idx+1) {
            starView.percent = 1;
        }else{
            switch (_showStarDrawStyle) {
                case RSShowStarDrawStyleComplete:
                {
                    CGFloat percent = starScore - idx;
                    if (percent <= 0) {
                        starView.percent = 0;
                    }else{
                        starView.percent = 1;
                    }
                }
                break;
                case RSShowStarDrawStyleCompleteAndHalf:
                {
                    CGFloat percent = starScore - idx;
                    if (percent <= 0.5) {
                        if (percent>0) {
                            starView.percent = 0.5;
                        }else{
                            starView.percent = 0;
                        }
                    }else{
                        starView.percent = 1;
                    }
                }
                break;
                case RSShowStarDrawStyleFree:
                {
                    CGFloat percent = starScore - idx;
                    starView.percent = percent;
                }
                break;
                default:
                break;
            }
        }
    }];
}


#pragma mark    - 设置颜色、线宽、
//设置线宽
- (void)setLineWidth:(CGFloat)lineWidth{
    _lineWidth = lineWidth;
    [self upDateStarViews];
}

//设置线的颜色
- (void)setLineColor:(UIColor *)lineColor{
    _lineColor = lineColor;
    [self upDateStarViews];
    
}

//设置填充颜色
- (void)setFillColor:(UIColor *)fillColor{
    _fillColor = fillColor;
    [self upDateStarViews];
//    UIViewAnimationTransitionNone
}


#define mark - 手势移动
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    CGPoint point = [[touches anyObject] locationInView:self];
    NSLog(@"touchPoint=%@",NSStringFromCGPoint(point));
    
    _defaultScore   =   [self calculateScoreWithPoint:point];
    
    [self updateViewsWithScore:_defaultScore];
    if (self.scoreBlock) {
        self.scoreBlock([self cheackReturnScore:_defaultScore]);
    }
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint point = [[touches anyObject] locationInView:self];
    NSLog(@"MovePoint=%@",NSStringFromCGPoint(point));
    
    _defaultScore =  [self calculateScoreWithPoint:point];
    
    [self updateViewsWithScore:_defaultScore];
    if (self.scoreBlock) {
        self.scoreBlock([self cheackReturnScore:_defaultScore]);
    }
}
#pragma mark 根据点击、滑动位置计算当前点亮星星数量
- (CGFloat)calculateScoreWithPoint:(CGPoint)point
{
    CGFloat newRating   =   0;
    CGRect firstStarRect =   CGRectFromString(_starFrameMuAry.firstObject);
    CGRect lastStarRect =   CGRectFromString(_starFrameMuAry.lastObject);
    
    if (point.x<=CGRectGetMinX(firstStarRect)) {
        newRating   =   0;
    }else if (point.x>=CGRectGetMaxX(lastStarRect)){
        newRating   =   _starCount;
    }else{
        for (int i=0; i<_starFrameMuAry.count; i++) {
            CGRect starRect =   CGRectFromString(_starFrameMuAry[i]);
            if (point.x>=CGRectGetMinX(starRect) && point.x<=CGRectGetMaxX(starRect)+_space) {
                CGFloat  decimalPart    =   (point.x-CGRectGetMinX(starRect))/_star_WY;
                newRating = i + (decimalPart>1?1:decimalPart);
                break;
            }
        }
        
        return [self cheackReturnScore:newRating];
    }
    
    return newRating;
}

#pragma mark   - set
//设置分数
- (void)setDefaultScore:(CGFloat)defaultScore{
    _defaultScore   =   defaultScore;
    [self updateViewsWithScore:_defaultScore];
}
#pragma mark    是否允许滑动改变点亮数量
- (void)setShowStarStyle:(RSShowStarStyle)showStarStyle
{
    _showStarStyle  =   showStarStyle;
    switch (showStarStyle) {
        case RSShowStarStyleReadonly:
        {
            self.userInteractionEnabled = NO;
        }
            break;
        case RSShowStarStyleReadAndWrite:
        {
            self.userInteractionEnabled = YES;
        }
            break;
        default:
            break;
    }
}
- (void)setStarAlignment:(RSShowStarAlignment)starAlignment
{
    _starAlignment  =   starAlignment;
    [self setupConfigurationProperty];
    [self setNeedsLayout];
}

- (void)setShowStarDrawStyle:(RSShowStarDrawStyle)showStarDrawStyle
{
    _showStarDrawStyle  =   showStarDrawStyle;
    [self updateViewsWithScore:_defaultScore];
    if (self.scoreBlock) {
        self.scoreBlock([self cheackReturnScore:_defaultScore]);
    }
}

#pragma mark    - 懒加载
- (NSMutableArray *)starArray{
    if (!_starArray) {
        _starArray = [NSMutableArray array];
    }
    return _starArray;
}
- (NSMutableArray *)starFrameMuAry{
    if (!_starFrameMuAry) {
        _starFrameMuAry =   [NSMutableArray array];
    }
    return _starFrameMuAry;
}

@end
